package com.example.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Re;
import com.example.dto.DishDto;
import com.example.entity.Dish;
import com.example.service.IDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 菜品管理
 * </p>
 *
 * @author czx
 * @since 2022-04-28
 */
@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {

    @Resource
    private IDishService dishService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 新增菜品
     *
     * @param dishDto 数据传输对象
     * @return 新增结果
     */
    @PostMapping
    public Re<String> save(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        boolean save = dishService.saveWithFlavor(dishDto);
        if (save) {
            // 清理某个分类下面的菜品缓存数据
            String key = "dish_" + dishDto.getCategoryId() + "_1";
            stringRedisTemplate.delete(key);
            return Re.success("新增菜品成功");
        }
        return Re.error("新增菜品失败");
    }

    /**
     * 分页查询菜品
     *
     * @param page     页数
     * @param pageSize 页大小
     * @param name     菜品名
     * @return 结果类
     */
    @GetMapping("/page")
    public Re<Page<DishDto>> page(int page, int pageSize, String name) {
        log.info("菜品分页查询条件:page={},pageSize={},name={}", page, pageSize, name);
        Page<DishDto> pageInfo = dishService.page(page, pageSize, name);
        return Re.success(pageInfo);
    }

    /**
     * 回显菜品信息
     *
     * @param id 菜品id
     * @return 回显结果
     */
    @GetMapping("/{id}")
    public Re<DishDto> getById(@PathVariable Long id) {
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        if (dishDto != null) {
            return Re.success(dishDto);
        }
        return Re.error("菜品回显失败");
    }

    /**
     * 更新菜品信息
     *
     * @return 更新结果
     */
    @PutMapping
    public Re<String> update(@RequestBody DishDto dishDto) {
        log.info("更新菜品: {}", dishDto.getName());
        boolean update = dishService.updateWithFlavor(dishDto);
        if (update) {
            log.info("菜品修改成功");
            // 清理某个分类下面的菜品缓存数据
            String key = "dish_" + dishDto.getCategoryId() + "_1";
            stringRedisTemplate.delete(key);
            return Re.success("菜品修改成功");
        }
        return Re.error("菜品修改失败");
    }

    /**
     * 修改菜品的售卖状态
     *
     * @param status 更改后的状态
     * @param ids    （一或多种）菜品的id
     * @return 结果
     */
    @PostMapping("/status/{status}")
    public Re<String> updateByStatus(@PathVariable int status, Long[] ids) {
        boolean update;
        update = dishService.updateByStatus(status, ids);
        if (!update) return Re.error("更改菜品状态失败");
        for (Long id : ids) {
            // 清理某个分类下面的菜品缓存数据
            String key = "dish_" + id + "_1";
            stringRedisTemplate.delete(key);
        }
        return Re.success("更改菜品状态成功");
    }

    /**
     * 删除菜品，只有菜品为停售状态才能删除
     *
     * @param ids 菜品id
     * @return 结果
     */
    @DeleteMapping
    public Re<String> delete(@RequestParam List<Long> ids) {
        log.info("菜品删除中:  {} ", ids);
        boolean remove = dishService.removeWithDishFlavor(ids);
        if (remove) {
            return Re.success("菜品删除成功");
        }
        return Re.error("菜品删除失败");
    }

    /**
     * 菜品查询
     *
     * @param dish 查询条件
     * @return 结果
     */
    @GetMapping("/list")
    public Re<List<DishDto>> list(Dish dish) {
        // 创建key
        String key = "dish_" + dish.getCategoryId() + "_1";
        // 先从redis中获取缓存String数据
        String sJson = stringRedisTemplate.opsForValue().get(key);
        // 将Json数据对象转为列表
        List<DishDto> list = JSONObject.parseArray(sJson, DishDto.class);
        if (list != null) {
            return Re.success(list);
        }
        // 如果不存在，需要查询数据库，将查询  到的菜品数据缓存到redis中
        list = dishService.listWithDishFlavor(dish);
        // 先将列表对象转为Json对象再转为String对象
        String sList = JSONObject.toJSON(list).toString();
        // 缓存菜品数据60分钟
        stringRedisTemplate.opsForValue().set(key, sList, 60, TimeUnit.MINUTES);
        if (list != null) {
            return Re.success(list);
        }
        return Re.error("菜品查看失败");
    }
}
